package com.ruoyi.epidemic.handler;

import cn.hutool.json.JSONUtil;
import com.ruoyi.epidemic.domain.SysUserDept;
import com.ruoyi.epidemic.domain.WxCpSysDept;
import com.ruoyi.epidemic.domain.WxCpSysUser;
import com.ruoyi.epidemic.mapper.*;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpDepartmentService;
import me.chanjar.weixin.cp.api.impl.WxCpDepartmentServiceImpl;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.api.impl.WxCpUserServiceImpl;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wf
 * @date 2022年05月31日
 */
@Component
public class WxContactsSyncHandler {

    @Value("${wechat.cp.corpId}")
    private String corpId;

    @Value("${wechat.cp.appConfigs.agentId}")
    private Integer agentId;

    @Value("${wechat.cp.appConfigs.corpSecret}")
    private String corpsecret;

    @Value("${wechat.cp.appConfigs.token}")
    private String token;

    @Value("${wechat.cp.appConfigs.aesKey}")
    private String aesKey;

    @Autowired
    private SysUserDeptMapper sysUserDeptMapper;

    @Autowired
    private WxCpUserMapper wxCpUserMapper;

    @Autowired
    private WxCpDepartMapper wxCpDepartMapper;

    @Autowired
    private WxCpSysUserMapper wxCpSysUserMapper;

    @Autowired
    private WxCpSysDeptMapper wxCpSysDeptMapper;

    private static final Logger log = LoggerFactory.getLogger(WxContactsSyncHandler.class);

    /**
     * @description:  获取企业微信通讯录部门列表
     * @param:
     * @return: java.util.List<me.chanjar.weixin.cp.bean.WxCpDepart>
     * @author
     * @date: 2022/6/1 15:59
     */
    public List<WxCpDepart> getDepartmentList() throws WxErrorException {
        WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
        config.setCorpId(corpId);      // 设置微信企业号的appid
        config.setCorpSecret(corpsecret);  // 设置微信企业号的app corpSecret

        WxCpServiceImpl wxCpService = new WxCpServiceImpl();
        wxCpService.setWxCpConfigStorage(config);

        WxCpDepartmentService wxCpDepartmentService = new WxCpDepartmentServiceImpl(wxCpService);

        List<WxCpDepart> departList =  wxCpDepartmentService.list(null);
        log.info("============获取企业微信通讯录部门列表完成===============");
        return departList;
    }

    /**
     * @description:  获取企业微信通讯录人员列表
     * @param: departList
     * @return:
     * @author
     * @date: 2022/6/1 16:00
     */
    public List<WxCpUser> getUserList(List<WxCpDepart> departList) throws WxErrorException {
        WxCpDefaultConfigImpl config = new WxCpDefaultConfigImpl();
        config.setCorpId(corpId);      // 设置微信企业号的appid
        config.setCorpSecret(corpsecret);  // 设置微信企业号的app corpSecret

        List<WxCpDepart> companys = departList.stream().filter(d -> d.getParentId() == 0).collect(Collectors.toList());

        WxCpDepart company = companys.get(0);

        WxCpServiceImpl wxCpService = new WxCpServiceImpl();
        wxCpService.setWxCpConfigStorage(config);

        WxCpUserServiceImpl wxCpUserService = new WxCpUserServiceImpl(wxCpService);

        List<WxCpUser> userList =  wxCpUserService.listSimpleByDepartment(company.getId(),true, 0);
        log.info("============获取企业微信通讯录人员列表完成===============");
        return userList;
    }


    /**
     * @description:  处理企业微信通讯录全量同步
     * @param: null
     * @return:
     * @author
     * @date: 2022/6/1 16:02
     */
    @Transactional(rollbackFor = Exception.class)
    public void sync () throws WxErrorException {

        log.info("============开始处理微信通讯录全量同步===============");
        List<com.ruoyi.epidemic.domain.WxCpDepart> wxDepartInsertList = new ArrayList<com.ruoyi.epidemic.domain.WxCpDepart>();
        List<WxCpSysDept> departInsertList = new ArrayList<WxCpSysDept>();
        List<com.ruoyi.epidemic.domain.WxCpUser> wxUserInsertList = new ArrayList<>();
        List<WxCpSysUser> userInsertList = new ArrayList<WxCpSysUser>();
        List<SysUserDept> userDeptInsertList = new ArrayList<SysUserDept>();

        List<WxCpDepart> departList = this.getDepartmentList();
        List<WxCpUser> userList = this.getUserList(departList);

        Date createTime = new Date();

        for(WxCpDepart depart : departList){

            //保存企业微信部门信息
            com.ruoyi.epidemic.domain.WxCpDepart wxCpDepart = new com.ruoyi.epidemic.domain.WxCpDepart();
            wxCpDepart.setDeptId(depart.getId());
            wxCpDepart.setParentId(depart.getParentId());
            wxCpDepart.setDeptName(depart.getName());
            wxCpDepart.setOrderNum(depart.getOrder());
            wxCpDepart.setDelFlag("0");
            wxCpDepart.setCreateTime(createTime);
            wxDepartInsertList.add(wxCpDepart);

            //保存部门信息
            WxCpSysDept sysDept = new WxCpSysDept();
            sysDept.setDeptId(depart.getId());
            sysDept.setParentId(depart.getParentId());
            sysDept.setDeptName(depart.getName());
            sysDept.setOrderNum(depart.getOrder());
            sysDept.setDelFlag("0");
            sysDept.setCreateTime(createTime);
            departInsertList.add(sysDept);
        }

        for(WxCpUser user : userList){

            String userId = user.getUserId();
            Long[] departIds = user.getDepartIds();
            String name = user.getName();

            com.ruoyi.epidemic.domain.WxCpUser wxCpUser = new com.ruoyi.epidemic.domain.WxCpUser();
            //保存企业微信员工信息
            wxCpUser.setUserId(userId);
            wxCpUser.setDeptIds(JSONUtil.toJsonStr(departIds));
            wxCpUser.setLoginName(name);
            wxCpUser.setUserName(name);
            wxCpUser.setDelFlag("0");
            wxCpUser.setCreateTime(createTime);
            wxUserInsertList.add(wxCpUser);

            //保存员工信息
            WxCpSysUser sysUser = new WxCpSysUser();
            sysUser.setUserId(userId);
            sysUser.setLoginName(name);
            sysUser.setUserName(name);
            sysUser.setDelFlag("0");
            sysUser.setCreateTime(createTime);
            userInsertList.add(sysUser);

            //保存员工-部门关系信息
            for(Long departId : departIds){
                SysUserDept sysUserDept = new SysUserDept();
                sysUserDept.setUserId(userId);
                sysUserDept.setDeptId(departId);
                sysUserDept.setCreateTime(createTime);
                userDeptInsertList.add(sysUserDept);
            }
        }

        handleWxCpDepart(wxDepartInsertList);
        handleWxCpSysDept(departInsertList);
        handleWxCpUser(wxUserInsertList);
        handleWxCpSysUser(userInsertList);
        handleSysUserDept(userDeptInsertList);

        log.info("============处理微信通讯录全量同步完成===============");
    }

    /**
     * @description:  处理微信通讯录人员同步
     * @param: wxUserInsertList
     * @return: void
     * @author
     * @date: 2022/6/1 11:09
     */
    public void handleWxCpUser(List<com.ruoyi.epidemic.domain.WxCpUser> wxUserInsertList){

//        wxCpUserMapper.deleteWxCpUserAll();

        //比对数据，将企业微信已经删除的人员更新到系统数据中
        //获取系统数据
        //过滤委外人员
        com.ruoyi.epidemic.domain.WxCpUser selectUser = new com.ruoyi.epidemic.domain.WxCpUser();
        selectUser.setUserType("00");
        List<com.ruoyi.epidemic.domain.WxCpUser> oldUserList = wxCpUserMapper.selectWxCpUserList(selectUser);
        //获取企业微信已经删除数据
        List<com.ruoyi.epidemic.domain.WxCpUser> deleteUserList = oldUserList.stream()
                .filter(deleteUser -> !wxUserInsertList.stream().map(all -> all.getUserId()).collect(Collectors.toList()).contains(deleteUser.getUserId()))
                .collect(Collectors.toList());
        for(com.ruoyi.epidemic.domain.WxCpUser user : deleteUserList){
            user.setStatus("1");
            user.setDelFlag("2");
            user.setUpdateTime(new Date());
            wxCpUserMapper.updateWxCpUser(user);
        }

        int a = 1000;//每次提交1000条
        int loop = (int) Math.ceil(wxUserInsertList.size() / (double) a);
        List<com.ruoyi.epidemic.domain.WxCpUser> tempList = new ArrayList<com.ruoyi.epidemic.domain.WxCpUser>(a);
        int start, stop;
        for (int i = 0; i < loop; i++) {
            tempList.clear();
            start = i * a;
            stop = Math.min(i * a + a - 1, wxUserInsertList.size() - 1);
            System.out.println("range:" + start + " - " + stop);
            for (int j = start; j <= stop; j++) {
                tempList.add(wxUserInsertList.get(j));
            }
            wxCpUserMapper.batchReplace(tempList);
            System.out.println("已经插入" + (stop + 1) + " 条");
        }
        log.info("============处理微信通讯录人员同步完成===============");
    }

    /**
     * @description:  处理微信通讯录系统人员
     * @param: userInsertList
     * @return:
     * @author
     * @date: 2022/6/1 11:09
     */
    public void handleWxCpSysUser( List<WxCpSysUser> userInsertList){
        //比对数据，将企业微信已经删除的人员更新到系统数据中
        //获取系统数据
        //过滤委外人员
        WxCpSysUser selectUser = new WxCpSysUser();
        selectUser.setUserType("00");
        List<WxCpSysUser> oldUserList = wxCpSysUserMapper.selectWxCpSysUserList(selectUser);
        //获取企业微信已经删除数据
        List<WxCpSysUser> deleteUserList = oldUserList.stream()
                .filter(deleteUser -> !userInsertList.stream().map(all -> all.getUserId()).collect(Collectors.toList()).contains(deleteUser.getUserId()))
                .collect(Collectors.toList());
        for(WxCpSysUser user : deleteUserList){
            user.setStatus("1");
            user.setDelFlag("2");
            user.setUpdateTime(new Date());
            wxCpSysUserMapper.updateWxCpSysUser(user);
        }

        int a = 1000;//每次提交1000条
        int loop = (int) Math.ceil(userInsertList.size() / (double) a);
        List<WxCpSysUser> tempList = new ArrayList<WxCpSysUser>(a);
        int start, stop;
        for (int i = 0; i < loop; i++) {
            tempList.clear();
            start = i * a;
            stop = Math.min(i * a + a - 1, userInsertList.size() - 1);
            System.out.println("range:" + start + " - " + stop);
            for (int j = start; j <= stop; j++) {
                tempList.add(userInsertList.get(j));
            }
            wxCpSysUserMapper.batchReplace(tempList);
            System.out.println("已经插入" + (stop + 1) + " 条");
        }
        log.info("============处理微信通讯录系统人员同步完成===============");
    }


    /**
     * @description:  处理微信通讯录部门同步
     * @param: wxDepartInsertList
     * @return:
     * @author
     * @date: 2022/6/1 11:31
     */

    public void handleWxCpDepart(List<com.ruoyi.epidemic.domain.WxCpDepart> wxDepartInsertList){
        wxCpDepartMapper.deleteWxCpDepartAll();
        wxCpDepartMapper.batchInsert(wxDepartInsertList);
        log.info("============处理微信通讯录部门同步完成===============");
    }

    /**
     * @description:  处理微信通讯录系统部门同步
     * @param: wxUserInsertList
     * @return: void
     * @author
     * @date: 2022/6/1 11:32
     */
    public void handleWxCpSysDept(List<WxCpSysDept> departInsertList){
        wxCpSysDeptMapper.deleteWxCpSysDepartAll();
        wxCpSysDeptMapper.batchInsert(departInsertList);
        log.info("============处理微信通讯录系统部门同步完成===============");
    }

    /**
     * @description:  处理系统部门-用户关联表同步
     * @param: userDeptInsertList
     * @return: void
     * @author
     * @date: 2022/6/1 11:32
     */
    public void handleSysUserDept(List<SysUserDept> userDeptInsertList){
        sysUserDeptMapper.deleteSysUserDeptAll();
        int a = 1000;//每次提交1000条
        int loop = (int) Math.ceil(userDeptInsertList.size() / (double) a);
        List<SysUserDept> tempList = new ArrayList<SysUserDept>(a);
        int start, stop;
        for (int i = 0; i < loop; i++) {
            tempList.clear();
            start = i * a;
            stop = Math.min(i * a + a - 1, userDeptInsertList.size() - 1);
            System.out.println("range:" + start + " - " + stop);
            for (int j = start; j <= stop; j++) {
                tempList.add(userDeptInsertList.get(j));
            }
            sysUserDeptMapper.batchReplace(tempList);
            System.out.println("已经插入" + (stop + 1) + " 条");
        }
        log.info("============处理系统部门-用户关联表同步完成===============");
    }


}
